Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

441
Visualizações
Advertencia de Xcode 13.3: "'self' se refiere al método '{object}.self', que puede ser inesperado

Acabo de actualizar a Xcode 13.3 y veo varias instancias de una nueva advertencia que no había visto con versiones anteriores de Xcode. Como ejemplo, tengo una celda de vista de tabla simple llamada LabelAndSwitchTableViewCell que se ve así:

 import UIKit class LabelAndSwitchTableViewCell: UITableViewCell { private let label: UILabel = { let label = UILabel() label.translatesAutoresizingMaskIntoConstraints = false return label }() private let _switch: UISwitch = { let _switch = UISwitch() _switch.translatesAutoresizingMaskIntoConstraints = false _switch.addTarget(self, action: #selector(didToggleSwitch), for: .valueChanged) return _switch }() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) contentView.addSubview(label) contentView.addSubview(_switch) // layout constraints removed for brevity } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @objc private func didToggleSwitch() { print("Switch was toggled...") } }

Como puede ver, estoy agregando un objetivo al interruptor al que quiero que se llame cuando cambie el valor de los interruptores:

 _switch.addTarget(self, action: #selector(didToggleSwitch), for: .valueChanged)

Después de actualizar a Xcode 13.3, ahora veo una nueva advertencia en esta línea:

 'self' refers to the method 'LabelAndSwitchTableViewCell.self', which may be unexpected

La sugerencia de Xcode para silenciar esta advertencia es reemplazar:

 _switch.addTarget(self, action: #selector(didToggleSwitch), for: .valueChanged)

...con...

 _switch.addTarget(LabelAndSwitchTableViewCell.self, action: #selector(didToggleSwitch), for: .valueChanged)

Hacer este cambio silencia la advertencia, pero también hace que la aplicación se bloquee (selector no reconocido) cuando alterno el interruptor. Aquí está el volcado de ese accidente:

 [app_mockup.LabelAndSwitchTableViewCell didToggleSwitch]: unrecognized selector sent to class 0x1043d86e8 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[app_mockup.LabelAndSwitchTableViewCell didToggleSwitch]: unrecognized selector sent to class 0x1043d86e8'

Hacer que el método didToggleSwitch() sea static evitará el bloqueo, pero no estoy seguro de por qué querría hacer eso. Obviamente, puedo revertir el cambio (de LabelAndSwitchTableViewCell.self de nuevo a solo self ), pero me pregunto si hay algo más que debería hacer para abordar esto.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Puedes arreglarlo cambiando los let a lazy var's

 private lazy var _switch2: UISwitch = { let _switch = UISwitch() _switch.translatesAutoresizingMaskIntoConstraints = false _switch.addTarget(self, action: #selector(didToggleSwitch), for: .valueChanged) return _switch }()

La sugerencia de corrección de Xcode es simplemente incorrecta.

over 4 years ago · Santiago Trujillo Relatório

0

El motivo es que self aún no está listo en la fase 1 de inicialización del objeto. La fase 1 es para configurar todas las propiedades almacenadas, y solo en la fase 2, puede acceder a self .

Para corregir su código, puede usar la propiedad lazy , donde se completa la fase de inicialización 1.

Aquí está la referencia: https://docs.swift.org/swift-book/LanguageGuide/Initialization.html ingrese la descripción de la imagen aquí

Para esta advertencia:

  1. Si no hay una superclase, o la superclase no es NSObject , self es un error cuando se usa directamente en una propiedad almacenada.
  2. Si la superclase es NSObject , self se compila en un cierre automático (ClassXXX) -> () -> ClassXXX . Entonces, en tiempo de ejecución, self se usará como instancia actual. Pero, dado que Swift 5.6 nos advierte sobre eso, creo que la referencia de self en la propiedad almacenada de una subclase NSObject puede no estar permitida en futuras versiones de Swift.

Ejemplo 1: error cuando no hay superclase ingrese la descripción de la imagen aquí

Ejemplo 2: el yo compilado en AST

Para este código:

 import Foundation class MyTest: NSObject { var myself = self }

Aquí hay parte del AST compilado: ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda